﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Mail;
using SportsStore.Domain.Abstract;

namespace SportsStore.Domain.Entities
{
    public class EmailSettings
    {
        public EmailSettings()
        {
            this.MailToAddress = "orders@example.com";
            this.MailFromAddress = "sportsstore@example.com";
            this.UseSsl = true;
            this.Username = "MySmtpUsername";
            this.Password = "MySmtpPassword";
            this.ServerName = "smtp.example.com";
            this.ServerPort = 587;
            this.WriteAsFile = false;
            this.FileLocation = @"D:\sports_store_emails";
        }

        public string MailToAddress { get; set; }
        public string MailFromAddress { get; set; }
        public bool UseSsl { get; set; }
        public string Username { get; set; }
        public string Password { get; set; }
        public string ServerName { get; set; }
        public int ServerPort { get; set; }
        public bool WriteAsFile { get; set; }
        public string FileLocation { get; set; }
    }

    public class EmailOrderProcessor : IOrderProcessor
    {
        public EmailOrderProcessor( EmailSettings settings )
        {
            this.EmailSettings = settings;
        }

        private EmailSettings EmailSettings { get; set; }

        public void ProcessOrder( Cart cart, ShippingDetails shippingDetails )
        {
            using ( var smtpClient = new SmtpClient() )
            {
                smtpClient.EnableSsl = this.EmailSettings.UseSsl;
                smtpClient.Host = this.EmailSettings.ServerName;
                smtpClient.Port = this.EmailSettings.ServerPort;
                smtpClient.UseDefaultCredentials = false;
                smtpClient.Credentials = new NetworkCredential( this.EmailSettings.Username, this.EmailSettings.Password );

                // If there is no real SMTP Server, 
                // Set EmailSettings.WriteAsFile as true to allow email message written 
                // into the designated directory, in this case "D:\sports_store_emails"
                this.EmailSettings.WriteAsFile = true;

                if ( this.EmailSettings.WriteAsFile )
                {
                    smtpClient.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory;
                    smtpClient.PickupDirectoryLocation = this.EmailSettings.FileLocation;
                    smtpClient.EnableSsl = false;
                }

                var body = new StringBuilder()
                    .AppendLine( "A new order has been submitted" )
                    .AppendLine( "---" )
                    .AppendLine( "Items" );

                foreach ( var line in cart.Lines )
                {
                    var subtotal = line.Product.Price * line.Quantity;
                    body.AppendFormat( "{0} x {1} (subtotal: {2:c}", line.Quantity, line.Product.Name, subtotal );
                }

                body.AppendFormat( "Total order value: {0:c}", cart.ComputeTotalValue() )
                    .AppendLine( "---" )
                    .AppendLine( "Ship to: " )
                    .AppendLine( shippingDetails.Name )
                    .AppendLine( shippingDetails.Line1 )
                    .AppendLine( shippingDetails.Line2 ?? "" )
                    .AppendLine( shippingDetails.Line3 ?? "" )
                    .AppendLine( shippingDetails.City )
                    .AppendLine( shippingDetails.State ?? "" )
                    .AppendLine( shippingDetails.Country )
                    .AppendLine( shippingDetails.Zip )
                    .AppendLine( "---" )
                    .AppendFormat( "Gift Wrap: {0}", shippingDetails.GiftWrap ? "Yes" : "No" );

                var mailMessage = new MailMessage(
                    this.EmailSettings.MailFromAddress, // From
                    this.EmailSettings.MailToAddress,   // To
                    "New order submitted",              // Subject
                    body.ToString() );                  // Body

                if ( this.EmailSettings.WriteAsFile )
                    mailMessage.BodyEncoding = Encoding.ASCII;

                smtpClient.Send( mailMessage );
            }
        }
    }
}
